package utils;

import java.lang.reflect.Constructor;
import java.util.HashMap;

import javax.sql.DataSource;

import org.springframework.aop.framework.ProxyFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;

public class TranscationProxy {
	private static HashMap<DataSource,TransactionInterceptor> map = new HashMap<DataSource,TransactionInterceptor>();
	
	public static Object getTranscationProxy(Class<?> c, DataSource dataSource) throws Exception {
		TransactionInterceptor txInterceptor = getTransactionInterceptor(dataSource);

		Constructor<?> constructor = c.getConstructor(new Class[]{DataSource.class});
		Object o = constructor.newInstance(new Object[]{dataSource});
		ProxyFactory factory = new ProxyFactory(o);
		factory.addAdvice(txInterceptor);		
		Object proxy = (Object) factory.getProxy();
		return proxy;
	}
	
	//	should be syncronized
	private synchronized static TransactionInterceptor getTransactionInterceptor(DataSource dataSource) {
		TransactionInterceptor txInterceptor = (TransactionInterceptor)map.get(dataSource);
		if( txInterceptor == null ){
			DataSourceTransactionManager txManager = (DataSourceTransactionManager)SpringBeanProxy.getBean("txManager");
			txManager.setDataSource(dataSource);
			txInterceptor = (TransactionInterceptor)SpringBeanProxy.getBean("txInterceptor");
			txInterceptor.setTransactionManager(txManager);
			map.put(dataSource,txInterceptor);
		}
		return txInterceptor;
	}
}
